package top.happylaishop.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import top.happylaishop.shop.common.Const;
import top.happylaishop.shop.dao.CartDao;
import top.happylaishop.shop.dao.ProductDao;
import top.happylaishop.shop.dto.CartDto;
import top.happylaishop.shop.dto.CartProductDto;
import top.happylaishop.shop.dto.UpdateCartProductDto;
import top.happylaishop.shop.dto.UserDto;
import top.happylaishop.shop.pojo.Cart;
import top.happylaishop.shop.pojo.Product;
import top.happylaishop.shop.service.CartService;
import top.happylaishop.shop.utils.CommonUtils;
import top.happylaishop.shop.utils.resp.RestResponse;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
public class CartServiceImpl implements CartService {

    @Value("${web.file.prefix}")
    private String webFilePrefix;

    @Autowired
    private CartDao cartDao;
    @Autowired
    private ProductDao productDao;

    @Override
    public RestResponse<CartDto> add(UpdateCartProductDto updateCartProductDto) {
        Cart cart = getCartProductByUserIdProductId(updateCartProductDto.getUserId(), updateCartProductDto.getProductId());
        if(cart == null){
            //这个产品不在这个购物车里,需要新增一个这个产品的记录
            Cart cartItem = new Cart();
            cartItem.setQuantity(updateCartProductDto.getCount());
            cartItem.setChecked(Const.Cart.CHECKED);
            cartItem.setProductId(updateCartProductDto.getProductId());
            cartItem.setUserId(updateCartProductDto.getUserId());
            cartItem.setCreateTime(new Date());
            cartItem.setUpdateTime(cartItem.getCreateTime());
            cartDao.insert(cartItem);
        }else{
            //这个产品已经在购物车里了.
            //如果产品已存在,数量相加
            cart.setQuantity(cart.getQuantity() + updateCartProductDto.getCount());
            cart.setUpdateTime(new Date());
            cartDao.updateById(cart);
        }
        return RestResponse.defaultSucessData(this.list(updateCartProductDto.getUserId()));
    }

    private Cart getCartProductByUserIdProductId(Integer userId, Integer productId) {
        LambdaQueryWrapper<Cart> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Cart::getUserId, userId).eq(Cart::getProductId, productId);
        return cartDao.selectOne(lambdaQueryWrapper);
    }

    @Override
    public RestResponse<CartDto> update(UpdateCartProductDto updateCartProductDto) {
        Cart cart = getCartProductByUserIdProductId(updateCartProductDto.getUserId(), updateCartProductDto.getProductId());
        cart.setQuantity(updateCartProductDto.getCount());
        cartDao.updateById(cart);
        return RestResponse.defaultSucessData(this.list(updateCartProductDto.getUserId()));
    }

    @Override
    public RestResponse<CartDto> deleteProduct(UserDto userDto, String productIds) {
        List<String> productIdList = Splitter.on(",").omitEmptyStrings().splitToList(productIds);
        LambdaQueryWrapper<Cart> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Cart :: getUserId, userDto.getId()).in(Cart::getProductId, productIdList);
        cartDao.delete(lambdaQueryWrapper);
        return RestResponse.defaultSucessData(list(userDto.getId()));
    }

    @Override
    public CartDto list(Integer userId) {
        CartDto cartDto = new CartDto();
        LambdaQueryWrapper<Cart> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Cart::getUserId, userId);
        List<Cart> records = cartDao.selectList(lambdaQueryWrapper);
        List<CartProductDto> cartProductVoList = Lists.newArrayList();
        List<Integer> selectedProductIds = Lists.newArrayList();
        BigDecimal cartTotalPrice = new BigDecimal("0");
        for (Cart record : records) {
            CartProductDto cartProductDto = new CartProductDto();
            cartProductDto.setId(record.getId());
            cartProductDto.setUserId(userId);
            cartProductDto.setProductId(record.getProductId());
            Product product = productDao.selectById(cartProductDto.getId());
            if(product != null){
                cartProductDto.setProductMainImage(product.getMainImage());
                cartProductDto.setProductName(product.getName());
                cartProductDto.setProductSubtitle(product.getSubtitle());
                cartProductDto.setProductStatus(product.getStatus());
                cartProductDto.setProductPrice(product.getPrice());
                cartProductDto.setProductStock(product.getStock());
                // 判断库存
                int buyLimitCount = 0;
                if(product.getStock() >= record.getQuantity()){
                    //库存充足的时候
                    buyLimitCount = record.getQuantity();
                    cartProductDto.setLimitQuantity(Const.Cart.LIMIT_NUM_SUCCESS);
                } else {
                    buyLimitCount = product.getStock();
                    cartProductDto.setLimitQuantity(Const.Cart.LIMIT_NUM_FAIL);
                    //购物车中更新有效库存
                    Cart cartForQuantity = new Cart();
                    cartForQuantity.setId(record.getId());
                    cartForQuantity.setQuantity(buyLimitCount);
                    cartDao.updateById(cartForQuantity);
                }
                cartProductDto.setQuantity(buyLimitCount);
                cartProductDto.setProductTotalPrice(CommonUtils.mul(product.getPrice().doubleValue(), cartProductDto.getQuantity()));
                cartProductDto.setProductChecked(record.getChecked());
                if(cartProductDto.getProductChecked() == Const.Cart.CHECKED){
                    cartTotalPrice = CommonUtils.add(cartTotalPrice, cartProductDto.getProductTotalPrice());
                    selectedProductIds.add(cartProductDto.getProductId());
                }
            }
            cartProductVoList.add(cartProductDto);
        }
        cartDto.setSelectedProductIdList(selectedProductIds);
        cartDto.setCartTotalPrice(cartTotalPrice);
        cartDto.setCartProductDtoList(cartProductVoList);
        cartDto.setAllChecked(this.getAllCheckedStatus(userId));
        cartDto.setImageHost(webFilePrefix);
        return cartDto;
    }

    private boolean getAllCheckedStatus(Integer userId){
        LambdaQueryWrapper<Cart> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Cart::getChecked, Const.Cart.UN_CHECKED)
            .eq(Cart::getUserId, userId);
        return cartDao.selectCount(lambdaQueryWrapper) == 0;
    }

    @Override
    public RestResponse<CartDto> selectOrUnSelect(UserDto userDto, Integer productId, Integer checked) {
        checkedOrUncheckedProduct(userDto.getId(), productId,checked);
        return RestResponse.defaultSucessData(list(userDto.getId()));
    }

    private void checkedOrUncheckedProduct(Integer userId, Integer productId, Integer checked) {
        Cart cart = new Cart();
        cart.setChecked(checked);
        UpdateWrapper<Cart> updateQueryWrapper = new UpdateWrapper<>();
        updateQueryWrapper.lambda().eq(Cart::getProductId, productId).eq(Cart::getUserId, userId);
        cartDao.update(cart, updateQueryWrapper);
    }

    @Override
    public RestResponse<Integer> getCartProductCount(Integer userId) {
        LambdaQueryWrapper<Cart> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Cart::getUserId, userId);
        return RestResponse.defaultSucessData(cartDao.selectCount(lambdaQueryWrapper));
    }

    @Override
    public RestResponse<CartDto> changeAllSelectedStatus(UserDto userDto, Integer checked) {
        Cart cart = new Cart();
        cart.setChecked(checked);
        UpdateWrapper<Cart> updateQueryWrapper = new UpdateWrapper<>();
        updateQueryWrapper.lambda().eq(Cart::getUserId, userDto.getId());
        cartDao.update(cart, updateQueryWrapper);
        return RestResponse.defaultSucessData(list(userDto.getId()));
    }

    @Override
    public List<Cart> listSelected(Integer userId) {
        LambdaQueryWrapper<Cart> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Cart :: getUserId, userId).in(Cart::getChecked, true);
        return cartDao.selectList(lambdaQueryWrapper);
    }

    @Override
    public int deleteByIds(List<Integer> idList) {
        return cartDao.deleteBatchIds(idList);
    }
}
